"""
实现流程：
    1:加载数据
    2：数据的预处理
    3：特征工程
        特征提取（归一化、标准化）
    4：模型训练（机器学习）
    5：模型预测
"""

#导包
from sklearn.datasets import  load_iris  #加载鸢尾花数据集(150条数据)
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split  # 分割训练集和测试集 (8:2 7:3)
from sklearn.preprocessing import  StandardScaler  # 数据标准化
from sklearn.neighbors import KNeighborsClassifier  #KNN算法 分类对象 因为鸢尾花是分类的场景 ，采用三分法
from sklearn.metrics import  accuracy_score  # 模型评估 计算模型准确率
import seaborn as sns

#1、定义函数 dm01_load_iris()
def dm01_load_iris():
    iris_data = load_iris()
    # print(iris_data)
    #{
    # "data":特征矩阵,
    # "target"：标签数据
    # "frame":None
    # "target_names":类别名称
    # "DESCR":数据集描述
    # "feature_names":特征名称
    # "filename":文件名称 iris.csv
    # "data_module":数据模块
    #}

    #2、打印试试
    #['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module']
    print(iris_data.keys())

    #3、查看数据集 特征字段
    print(iris_data.data[0:5])  #一共150个样本  每个样本4个特征 只看前5

    #4、查看数据集 标签字段
    print(iris_data.target[:52]) #[0 0 0 0 0]   前5个标签类别


    #5、查看数据集 标签名字
    print(iris_data.target_names)

    #6、查看数据集 特征名字
    print(iris_data.feature_names)


    #7、需求：打印描述信息 &框架信息&文件夹&数据模型


#2、定义函数 dm02_show_iris()
def dm02_show_iris():
    #1、加载数据
    iris_data = load_iris()
    #2、把上述的数据封装df对象
    iris_df=pd.DataFrame(iris_data.data,columns=iris_data.feature_names)
    #3、给df对象新增一个标签列
    iris_df['label']=iris_data.target
    # print(iris_df)

    #4、具体做可视化（了解）
    #参1：数据 iris_df
    #参2:x轴值  花瓣长度
    #参3：y轴值 花瓣宽度
    #参4：hue 颜色（根据鸢尾花的标签的分组，显示不同颜色）
    #参5：fit_reg=False  不绘制拟合回归线，True 绘制拟合回归线
    sns.lmplot(data=iris_df,x="petal length (cm)",y='petal width (cm)',hue='label',fit_reg=True)
    #5、设置标题
    plt.title("iris data")
    plt.tight_layout()#自动调整子图的参数
    plt.show()

#3、定义函数 dm03_train_test_split  实现训练集和测试集划分
def dm03_train_test_split():
    # 1、加载数据集
    iris_data = load_iris()  #150条  训练集 和测试集
    #2、划分数据集
    #iris_data.data  ->特征  150条
    #iris_data.target ->标签 150条
    #test_size ->表示测试集占比
    #random_state ->随机种子   如果种子一样，每次划分数据集都是一样的。                                     [0, 4294967295]
    x_train,x_test,y_train,y_test=train_test_split(iris_data.data,iris_data.target,test_size=0.2,random_state=4294967295)
    # print(f"训练集，x-特征:{len(x_train)}")  # 120条  每条4个列（特征）
    # print(f"训练集，y-标签：{len(y_train)}") # 120条  标签
    # print(f"测试集，x-特征：{len(x_test)}")# 30条  每条4个列（特征）
    # print(f"测试集，y-标签：{len(y_test)}")  #30条  标签
    print(f"x_train：{x_train}")

#
def dm04_模型评估与预测():
    #1、获取数据集
    iris_data=load_iris()

    #2、数据预处理（数据集划分）
    x_train,x_test,y_train,y_test=train_test_split(iris_data.data,iris_data.target,test_size=0.2,random_state=56)

    #3、特征工程之子工程_特征预处理（标准化） 演示！！因为源数据不存在量纲问题
    #3.1 创建标准化对象
    transfer=StandardScaler()
    #3.2 对特征列进行标准化  x_train：训练集特征  训练+转换
    x_train=transfer.fit_transform(x_train)
    #3.3 处理测试集  transform只有转换
    x_test=transfer.transform(x_test)
    #4、模型训练 -》机器学习
    #4.1 创建模型对象
    es=KNeighborsClassifier(n_neighbors=30)
    #4.2模型训练
    es.fit(x_train,y_train)  #训练集特征   训练集标签

    #5、模型预测   返回值是模型的预测值：y_predict
    y_predict=es.predict(x_test)

    #打印对比
    print(f"（测试集）预测结果为:{y_predict}")  # 30个预测标签
    print(f"（测试集）真实结果为:{y_test}")     # 30个真实标签




    #场景2：对新数据集做预测  （持久化本地）
    #第一步：定义新的数据集
    # x_test_new =[[2.1,3.5,5.6,3.2]]
    # #第二步：对新的数据集进行标准化
    # x_test_new = transfer.transform(x_test_new)
    # #第三步：对新数据集做预测，获取预测结果
    # y_test_new=es.predict(x_test_new)
    # print(f"（新数据集）预测结果为:{y_test_new}")
    #


    #
    #
    # #6.模型评估
    print(f"准确率:{es.score(x_test,y_test)}")
    #参1：测试集真实标签   参2：预测标签
    print(f"准确率:{accuracy_score(y_test,y_predict)}")













if __name__ == '__main__':
    # dm01_load_iris()
    # dm02_show_iris()
    # dm03_train_test_split()
    dm04_模型评估与预测()





